package com.fyp.ptma.dao.repository;

import java.util.List;

import javax.persistence.PersistenceException;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.exception.ConstraintViolationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.fyp.ptma.dao.repository.irepository.IDownloaderDao;
import com.fyp.ptma.model.Application;
import com.fyp.ptma.model.Downloader;
import com.fyp.ptma.model.Installation;
import com.fyp.ptma.model.Notification;

@Repository
public class DownloaderDao implements IDownloaderDao {
	@Autowired
	private SessionFactory sessionFactory;

	public Long save(Object objToSave) throws PersistenceException,
			ConstraintViolationException {
		Session session = this.openSession();
		session.save(objToSave);
		return 1L;
	}

	public Long update(Object objToUpdate) throws PersistenceException {
		// TODO Auto-generated method stub
		return null;
	}

	public boolean delete(Object objToDelete) throws PersistenceException,
			ConstraintViolationException {
		// TODO Auto-generated method stub
		return false;
	}

	public List<Application> getAllApplications(Downloader downloader)
			throws HibernateException {
		Session session = this.openSession();
		String strQuery = "Select app from Downloader as d Inner Join d.applications as app  where app.user.id = d.user.id and d.user.email = :devEmail and d.email = :yourEmail and d.deviceId = :deviceId";

		Query query = session.createQuery(strQuery);
		query.setString("devEmail", downloader.getUser().getEmail());
		query.setString("yourEmail", downloader.getEmail());
		query.setString("deviceId", downloader.getDeviceId());
		@SuppressWarnings("unchecked")
		List<Application> apps = query.list();

		return apps;
	}

	public Downloader getDownloaderByEmailAndDeviceId(Downloader downloader)
			throws HibernateException {
		Session session = this.openSession();
		String query = "select d from Downloader d where d.email =:email and d.deviceId = :deviceId and d.user.email = :emailDev ";

		Downloader dbObj = (Downloader) session.createQuery(query)
				.setParameter("email", downloader.getEmail())
				.setParameter("deviceId", downloader.getDeviceId())
				.setParameter("emailDev", downloader.getUser().getEmail())
				.uniqueResult();
		return dbObj;
	}

	public Session openSession() {
		return sessionFactory.getCurrentSession();
	}

	@Override
	public Long saveOrUpdate(Installation installation)
			throws HibernateException {

		Session session = this.openSession();
		session.saveOrUpdate(installation);

		return 1L;
	}

	@Override
	public Long saveOrUpdate(Downloader downloader) throws HibernateException {
		// TODO Auto-generated method stub
		Session session = this.openSession();
		session.saveOrUpdate(downloader);

		return downloader.getId();
	}

	@Override
	public List<Downloader> getDownloadersByDeviceIds(List<String> deviceIds,
			String authEmail) throws HibernateException {
		Session session = this.openSession();
		String strQuery = "from Downloader d where d.deviceId in (:deviceIds) and d.user.email = :authEmail";
		@SuppressWarnings("unchecked")
		List<Downloader> downloaders = session.createQuery(strQuery)
				.setParameterList("deviceIds", deviceIds)
				.setString("authEmail", authEmail).list();

		return downloaders;
	}

	@Override
	public void saveOrUpdate(Object objToSave) throws PersistenceException,
			ConstraintViolationException {
		// TODO Auto-generated method stub

	}

	public Installation getInstallation(Installation ins)
			throws HibernateException {

		String strQuery = "select i from Installation i inner join i.downloader d   where d.email = :myEmail and d.user.email = :devEmail and  i.installationPk.version = :version and  i.installationPk.nameSpace = :nameSpace";
		Session session = this.openSession();

		Query query = session.createQuery(strQuery);

		query.setParameter("myEmail", ins.getDownloader().getEmail());
		query.setParameter("devEmail", ins.getDownloader().getUser().getEmail());
		query.setParameter("version", ins.getInstallationPk().getVersion());
		query.setParameter("nameSpace", ins.getInstallationPk().getNameSpace());

		Installation notif = (Installation) query.uniqueResult();
		return notif;
	}

	@Override
	public Downloader getDownloaderByDeviceId(Downloader deviceId)
			throws HibernateException {
		Session session = this.openSession();
		String query = "select Distinct d from Downloader d where d.deviceId = :deviceId";

		Downloader dbObj = (Downloader) session.createQuery(query)

		.setParameter("deviceId", deviceId.getDeviceId()).uniqueResult();

		return dbObj;
	}
}
